home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 051-075 / 051 / sq.usq / usq.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  7KB  |  305 lines

  1. /* Program to unsqueeze files formed by sq.com
  2.  *
  3.  * Useage:
  4.  *
  5.  *    usq [-count] [-fcount] [file1] [file2] ... [filen]
  6.  *
  7.  * where file1 through filen represent one or more files to be compressed,
  8.  * and the following options may be specified:
  9.  *
  10.  *    -count        Previewing feature: redirects output
  11.  *             files to standard output with parity stripped
  12.  *            and unprintables except CR, LF, TAB and  FF
  13.  *            converted to periods. Limits each file
  14.  *            to first count lines.
  15.  *            Defaults to console, but see below how
  16.  *            to capture all in one file for further
  17.  *            processing, such as by PIP.
  18.  *            Count defaults to a very high value.
  19.  *            No CRC check is performed when previewing.
  20.  *            Use drive: to cancel this.
  21.  *
  22.  *    -fcount        Same as -count except formfeed
  23.  *            appended to preview of each file.
  24.  *            Example: -f10.
  25.  *
  26.  * If no such items are given on the command line you will be
  27.  * prompted for commands (one at a time). An empty command
  28.  * terminates the program.
  29.  *
  30.  * The unsqueezed file name is recorded in the squeezed file.
  31.  * 
  32.  */
  33. /* CHANGE HISTORY:
  34.  * 1.3    Close inbuff to avoid exceeding maximum number of
  35.  *    open files. Includes rearranging error exits.
  36.  * 1.4    Add -count option to allow quick inspection of files.
  37.  * 1.5  Break up long lines of introductory text
  38.  * 1.5  -count no longer appends formfeed to preview of each file.
  39.  *    -fcount (-f10, -F10) does append formfeed.
  40.  * 1.6  Modified to work correctly under MP/M II (DIO.C change) and
  41.  *      signon message shortened.
  42.  * 2.0    Modified to work with CI-C86 compiler (CP/M-86 and MS-DOS)
  43.  * 2.1  Modified for use in MLINK
  44.  * 2.2  Modified for use with optimizing CI-C86 compiler (MS-DOS)
  45.  * 3.0  Generalized for use under UNIX
  46.  * 3.3  Modified to work with c/70 (#define C70) as per Mike Barker.
  47.  *      Modified to work with ULTRIX (#define ULTRIX) as per Tom Reid.
  48.  *    Fixed non-ASCII name problem, as per Ted Medin.
  49.  */
  50.  
  51. /* eject eject */
  52.  
  53. #define SQMAIN
  54.  
  55. /*#define    ULTRIX        Comment out for non-ULTRIX systems.*/
  56. /*#define    C70        Comment out for non-c/70 systems.*/
  57.  
  58. #include <stdio.h>
  59. #include "sqcom.h"
  60. #include "usq.h"
  61. #define VERSION "3.3   10/29/86"
  62.  
  63. /* This must follow all include files */
  64. unsigned int dispcnt;    /* How much of each file to preview */
  65. char    ffflag;        /* should formfeed separate preview from different files */
  66.  
  67. main(argc, argv)
  68. int argc;
  69. char *argv[];
  70. {
  71.     int i,c;
  72.     char inparg[16];    /* parameter from input */
  73.  
  74.     dispcnt = 0;    /* Not in preview mode */
  75.  
  76.     printf("File unsqueezer version %s (original author: R. Greenlaw)\n\n", VERSION);
  77.  
  78.     /* Process the parameters in order */
  79.     for(i = 1; i < argc; ++i)
  80.         obey(argv[i]);
  81.  
  82.     if(argc < 2) {
  83.         printf("Enter file names, one line at a time, or type <RETURN> to quit.");
  84.         do {
  85.             printf("\n*");
  86.             for(i = 0; i < 16; ++i) {
  87.                 if((c = getchar()) == EOF)
  88.                     c = '\n';    /* force empty (exit) command */
  89.                 if((inparg[i] = c) == '\n') {
  90.                     inparg[i] = '\0';
  91.                     break;
  92.                 }
  93.             }
  94.             if(inparg[0] != '\0')
  95.                 obey(inparg);
  96.         } while(inparg[0] != '\0');
  97.     }
  98. }
  99.  
  100. /* eject eject */
  101.  
  102. obey(p)
  103. char *p;
  104. {
  105.     char *q, cc;
  106.  
  107.     if(*p == '-') {
  108.         if(ffflag = ((*(p+1) == 'F') || (*(p+1) == 'f')))
  109.             ++p;
  110.         /* Set number of lines of each file to view */
  111.         dispcnt = 65535;    /* default */
  112.         if(*(p+1))
  113.             if((dispcnt = atoi(p + 1)) == 0)
  114.                 printf("\nBAD COUNT %s", p + 1);
  115.         return;
  116.     }    
  117.  
  118.     /* Check for ambiguous (wild-card) name */
  119.     for(q = p; *q != '\0'; ++q)
  120.         if(*q == '*' || *q == '?') {
  121.             printf("\nCan't accept ambiguous name %s", p);
  122.             return;
  123.         }
  124.  
  125.     unsqueeze(p);
  126. }
  127.  
  128. /* eject eject */
  129.  
  130. unsqueeze(infile)
  131. char *infile;
  132. {
  133.     FILE *inbuff, *outbuff;    /* file buffers */
  134. #ifdef C70
  135.     int magictemp;
  136. #endif
  137.     int i, c;
  138.     char cc;
  139.  
  140.     char *p;
  141.     unsigned int filecrc;    /* checksum */
  142.     int numnodes;        /* size of decoding tree */
  143.     char outfile[128];    /* output file name */
  144.     unsigned int linect;    /* count of number of lines previewed */
  145.     char obuf[128];        /* output buffer */
  146.     int oblen;        /* length of output buffer */
  147.     static char errmsg[] = "ERROR - write failure in %s\n";
  148.  
  149. #if ULTRIX || AMIGA
  150.     if(!(inbuff=fopen(infile, "r"))) {
  151. #else
  152.     if(!(inbuff=fopen(infile, "rb"))) {
  153. #endif
  154.         printf("Can't open %s\n", infile);
  155.         return;
  156.     }
  157.     /* Initialization */
  158.     linect = 0;
  159.     crc = 0;
  160.     init_cr();
  161.     init_huff();
  162.  
  163.     /* Process header */
  164. #ifdef C70
  165.     magictemp = getx16(inbuff);
  166.     if(magictemp != RECOGNIZE) {
  167.         printf("magic number is %x, not %x.\n", magictemp,RECOGNIZE);
  168. #else
  169.     if(getx16(inbuff) != RECOGNIZE) {
  170.         printf("%s is not a squeezed file\n", infile);
  171. #endif
  172.         goto closein;
  173.     }
  174.  
  175. #ifdef C70
  176.     filecrc = getx16(inbuff);
  177. #else
  178.     filecrc = getw16(inbuff);
  179. #endif
  180.  
  181.     /* Get original file name */
  182.     p = outfile;            /* send it to array */
  183.     do {
  184. /*        *p = getc(inbuff);    */
  185.         *p = getc(inbuff) & 0x7f;    /*3.3 Must be ASCII.*/
  186.     } while(*p++ != '\0');
  187.  
  188.     printf("%s -> %s: ", infile, outfile);
  189.  
  190.  
  191. #ifdef C70
  192.     numnodes = getx16(inbuff);
  193. #else
  194.     numnodes = getw16(inbuff);
  195. #endif
  196.  
  197.     if(numnodes < 0 || numnodes >= NUMVALS) {
  198. #ifdef C70
  199.         printf("Number of nodes is %x, not %x.\n",numnodes,NUMVALS);
  200. #else
  201.         printf("%s has invalid decode tree size\n", infile);
  202. #endif
  203.         goto closein;
  204.     }
  205.  
  206.     /* Initialize for possible empty tree (SPEOF only) */
  207.     dnode[0].children[0] = -(SPEOF + 1);
  208.     dnode[0].children[1] = -(SPEOF + 1);
  209.  
  210.     /* Get decoding tree from file */
  211.     for(i = 0; i < numnodes; ++i) {
  212.         dnode[i].children[0] = getw16(inbuff);
  213.         dnode[i].children[1] = getw16(inbuff);
  214.     }
  215.  
  216.     if(dispcnt) {
  217.         /* Use standard output for previewing */
  218.         putchar('\n');
  219.         while(((c = getcr(inbuff)) != EOF) && (linect < dispcnt)) {
  220.             cc = 0x7f & c;    /* strip parity */
  221.             if((cc < ' ') || (cc > '~'))
  222.                 /* Unprintable */
  223.                 switch(cc) {
  224.                 case '\r':    /* return */
  225.                     /* newline will generate CR-LF */
  226.                     goto next;
  227.                 case '\n':    /* newline */
  228.                     ++linect;
  229.                 case '\f':    /* formfeed */
  230.                 case '\t':    /* tab */
  231.                     break;
  232.                 default:
  233.                     cc = '.';
  234.                 }
  235.             putchar(cc);
  236.         next: ;
  237.         }
  238.         if(ffflag)
  239.             putchar('\f');    /* formfeed */
  240.     } else {
  241.         /* Create output file */
  242. #if ULTRIX || AMIGA
  243.         if(!(outbuff=fopen(outfile, "w"))) {
  244. #else
  245.         if(!(outbuff=fopen(outfile, "wb"))) {
  246. #endif
  247.             printf("Can't create %s\n", outfile);
  248.             goto closeall;
  249.         }
  250.         printf("unsqueezing,");
  251.         /* Get translated output bytes and write file */
  252.         oblen = 0;
  253.         while((c = getcr(inbuff)) != EOF) {
  254.             crc += c;
  255.             obuf[oblen++] = c;
  256.             if (oblen >= sizeof(obuf)) {
  257.                 if(!fwrite(obuf, sizeof(obuf), 1, outbuff)) {
  258.                     printf(errmsg, outfile);
  259.                     goto closeall;
  260.                 }
  261.                 oblen = 0;
  262.             }
  263.         }
  264.         if (oblen && !fwrite(obuf, oblen, 1, outbuff)) {
  265.             printf(errmsg, outfile);
  266.             goto closeall;
  267.         }
  268.  
  269.         if((filecrc && 0xFFFF) != (crc && 0xFFFF))
  270.             printf("ERROR - checksum error in %s\n", outfile);
  271.         else    printf(" done.\n");
  272.  
  273.     closeall:
  274.         fclose(outbuff);
  275.     }
  276.  
  277. closein:
  278.     fclose(inbuff);
  279. }
  280.  
  281. getw16(iob)            /* get 16-bit word from file */
  282. FILE *iob;
  283. {
  284. int temp;
  285.  
  286. temp = getc(iob);        /* get low order byte */
  287. temp |= getc(iob) << 8;
  288. if (temp & 0x8000) temp |= (~0) << 15;    /* propogate sign for big ints */
  289. return (temp);
  290.  
  291. }
  292.  
  293.  
  294. getx16(iob)            /* get 16-bit (unsigned) word from file */
  295. FILE *iob;
  296. {
  297. int temp;
  298.  
  299. temp = getc(iob);        /* get low order byte */
  300. temp |= getc(iob) << 8;
  301. return(temp);
  302. }
  303.  
  304.  
  305.